package com.uwlaser.cut;

import com.uwlaser.http.exception.HttpCodeErrorException;
import com.uwlaser.http.exception.HttpException;
import com.uwlaser.http.exception.HttpResultErrorException;
import com.uwlaser.http.exception.HttpTimeoutException;
import com.uwlaser.modules.system.domain.SysExternalHttpLog;
import com.uwlaser.modules.system.domain.SysExternalSocketLog;
import com.uwlaser.modules.system.domain.SysExternalWebserviceLog;
import com.uwlaser.modules.system.service.SysExternalHttpLogService;
import com.uwlaser.modules.system.service.SysExternalSocketLogService;
import com.uwlaser.modules.system.service.SysExternalWebserviceLogService;
import com.uwlaser.socket.exception.TcpSocketCodeErrorException;
import com.uwlaser.socket.exception.TcpSocketException;
import com.uwlaser.socket.exception.TcpSocketResultErrorException;
import com.uwlaser.socket.exception.TcpSocketTimeoutException;
import com.uwlaser.utils.enums.DictValueEnum;
import com.uwlaser.webservice.exception.WebServiceCodeErrorException;
import com.uwlaser.webservice.exception.WebServiceException;
import com.uwlaser.webservice.exception.WebServiceResultErrorException;
import com.uwlaser.webservice.exception.WebServiceTimeoutException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * @Author QZK
 * @Description TODO 异常处理器
 * @Date 2022-12-06-17:33
 * @Version 1.0
 */
@Component
@RequiredArgsConstructor
public class BaseMethodExceptionHandler {

    /**
     * Socket 日志
     */
    private final SysExternalSocketLogService sysExternalSocketLogService;
    /**
     * WebService 日志
     */
    private final SysExternalWebserviceLogService sysExternalWebserviceLogService;
    /**
     * Http 日志
     */
    private final SysExternalHttpLogService sysExternalHttpLogService;

    /**
     * 处理调用外部系统的异常
     * @param e
     */
    public void handler(Exception e, long time) throws Exception {
        try {
            if(e instanceof TcpSocketException ){
                //处理Socket请求的异常
                handleTcpSocketException((TcpSocketException) e,time);
            } else if (e instanceof WebServiceException){
                //处理WebService请求的异常
                handleWebServiceException((WebServiceException) e,time);
            } else if (e instanceof HttpException) {
                //处理HTTP请求的异常
                handleHttpException((HttpException) e,time);
            } else {
                //其他类型的异常直接抛出
                throw e;
            }
        } catch (Exception ex){
            //统一用运行时异常抛出
            throw new RuntimeException(ex.getMessage(),ex);
        }

    }

    /**
     * 处理HttpException的异常
     * @param e
     * @param time
     */
    private void handleHttpException(HttpException e, long time) throws HttpException{
        long l = System.currentTimeMillis();
        //保存日志
        SysExternalHttpLog log = new SysExternalHttpLog();
        log.setUrl(e.getUrl());
        log.setRequestMethod(e.getRequestMethod());
        log.setParams(e.getParams());
        log.setParamType(e.getParamType());
        log.setSummarize(e.getDescribe());
        log.setErrorMsg(e.getMessage());
        log.setIsSuccess(DictValueEnum.IS_SUCCESS_N.getValue());
        log.setRetriesNum(0);
        log.setRequestResult(e.getRequestResult());
        log.setCreateBy("system");
        log.setElapsedTime((int) (l - time));
        log.setUpdateBy("system");

        sysExternalHttpLogService.addLog(log);
        if(e instanceof HttpCodeErrorException){
            //运行时代码错误或者数据错误
            //AOP也要对外抛出，让产线MES数据回滚，记录详细异常详细，修复异常后，能执行重传
            throw e;
        } else if (e instanceof HttpTimeoutException){
            //调用接口超时或者连接失败
            //AOP无需对外抛出，记录详细异常详细，执行重传机制，执行N次重传依然失败，自动切换离线模式
            return ;
        } else if (e instanceof HttpResultErrorException){
            //调用服务器接口返回的结果是异常的
            //记录详细异常详细，返NG给追溯,抛出异常
            throw e;
        } else {
            throw e;
        }
    }

    /**
     * 处理WebServiceException的异常
     * @param e
     */
    private void handleWebServiceException(WebServiceException e,long time) throws WebServiceException{
        long l = System.currentTimeMillis();
        //保存日志
        SysExternalWebserviceLog log = new SysExternalWebserviceLog();
        log.setUrl(e.getUrl());
        log.setMethodName(e.getMethodName());
        log.setBodyParams(e.getBodyParams());
        log.setHeaderParams(e.getHeaderParams());
        log.setSummarize(e.getDescribe());
        log.setErrorMsg(e.getMessage());
        log.setIsSuccess(DictValueEnum.IS_SUCCESS_N.getValue());
        log.setRetriesNum(0);
        log.setRequestResult(e.getRequestResult());
        log.setCreateBy("system");
        log.setElapsedTime((int) (l - time));
        log.setUpdateBy("system");

        sysExternalWebserviceLogService.addLog(log);
        if(e instanceof WebServiceCodeErrorException){
            //运行时代码错误或者数据错误
            //AOP也要对外抛出，让产线MES数据回滚，记录详细异常详细，修复异常后，能执行重传
            throw e;
        } else if (e instanceof WebServiceTimeoutException){
            //调用接口超时或者连接失败
            //AOP无需对外抛出，记录详细异常详细，执行重传机制，执行N次重传依然失败，自动切换离线模式
            return ;
        } else if (e instanceof WebServiceResultErrorException){
            //调用服务器接口返回的结果是异常的
            //记录详细异常详细，返NG给追溯,抛出异常
            throw e;
        } else {
            throw e;
        }
    }

    /**
     * 处理TCP Socket异常
     * @param e
     */
    private void handleTcpSocketException(TcpSocketException e,long time) throws TcpSocketException {
        long l = System.currentTimeMillis();
        //保存日志
        SysExternalSocketLog log = new SysExternalSocketLog();
        log.setHost(e.getHost());
        log.setPort(e.getPort());
        log.setParams(e.getParams());
        log.setConnectMode(e.getMode());
        log.setSummarize(e.getDescribe());
        log.setErrorMsg(e.getMessage());
        log.setIsSuccess(DictValueEnum.IS_SUCCESS_N.getValue());
        log.setRetriesNum(0);
        log.setRequestResult(e.getRequestResult());
        log.setCreateBy("system");
        log.setElapsedTime((int) (l - time));
        log.setUpdateBy("system");

        sysExternalSocketLogService.addLog(log);

        if(e instanceof TcpSocketCodeErrorException){
            //运行时代码错误或者数据错误
            //AOP也要对外抛出，让产线MES数据回滚，记录详细异常详细，修复异常后，能执行重传
            throw e;
        } else if (e instanceof TcpSocketTimeoutException){
            //调用接口超时或者连接失败
            //AOP无需对外抛出，记录详细异常详细，执行重传机制，执行N次重传依然失败，自动切换离线模式
            return ;
        } else if (e instanceof TcpSocketResultErrorException){
            //调用服务器接口返回的结果是异常的
            //记录详细异常详细，返NG给追溯,抛出异常
            throw e;
        } else {
            throw e;
        }
    }
}
